package ch.cryptobox.serivces;

import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.ArrayList;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;

import org.acplt.oncrpc.OncRpcException;

import ch.cryptobox.encryption.AES;
import ch.cryptobox.filehandles.FileHandle;
import ch.cryptobox.filehandles.FileHandleI;
import ch.cryptobox.nfsError.CreateFileException;
import ch.cryptobox.nfsError.FileNotFoundException;
import ch.cryptobox.nfsError.LookupException;
import ch.cryptobox.nfsError.ReadWriteException;
import ch.cryptobox.nfsclient.diropres;
import ch.cryptobox.nfsclient.fhandle;

public class EncryptedSyncronizationService implements SynchronizationService {

	private final SynchronizationService service;
	private final AES cypher;
	private final int id;

	public EncryptedSyncronizationService(final SynchronizationService service, final AES cypher, final int id) {
		this.service = service;
		this.cypher = cypher;
		this.id=id;

		this.cypher.regenerateKey(getId());
	}

	public EncryptedSyncronizationService(final SynchronizationService service, final AES cypher) {
		this(service,cypher,0);
	}

	@Override
	public void addFile(final File file, final byte[] data) throws OncRpcException,
	IOException, CreateFileException, ReadWriteException,FileNotFoundException {
		try {
			service.addFile(file, cypher.encrypt(data));
		} catch (final Exception ex) {
			ex.printStackTrace();
		}

	}

	@Override
	public void addDirectory(final File file) throws OncRpcException, IOException,
	CreateFileException, ReadWriteException,FileNotFoundException {
		service.addDirectory(file);
	}

	@Override
	public fhandle getRootDir() {
		return service.getRootDir();
	}

	@Override
	public byte[] readFile(final FileHandleI handle) throws OncRpcException,
	IOException, ReadWriteException {
		try {
			return cypher.decrypt(service.readFile(handle),handle.getDate(),getId());
		} catch (InvalidKeyException | IllegalBlockSizeException
				| BadPaddingException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public diropres lookup(final fhandle parent, final String name) throws OncRpcException,
	IOException {
		return service.lookup(parent, name);
	}

	@Override
	public diropres changeDir(final fhandle from, final String path)
			throws OncRpcException, IOException, CreateFileException,
			FileNotFoundException {

		return service.changeDir(from, path);
	}

	@Override
	public ArrayList<String> readDir(final fhandle dir) throws LookupException,
	OncRpcException, IOException {
		return service.readDir(dir);
	}

	@Override
	public FileHandleI getRootHandle() {
		return new FileHandle(this);
	}

	@Override
	public int getId() {
		return id;
	}

}
